#ifndef ANIMATIONSET_H
#define ANIMATIONSET_H

#include <vector>
#include <string>
#include <boost/shared_ptr.hpp>
#include <SFML/Graphics.hpp>
#include <pugixml/pugixml.hpp>

typedef boost::shared_ptr<sf::Image> ImagePtr;

class BaseAnimation
{
public:
	virtual ~BaseAnimation() {};
	virtual void Update(float dt) = 0;
	static std::string MakePath(const std::string& base, const std::string& name, const std::string& ext);
};

class AnimationSet;

class ImageAnimation: public BaseAnimation
{
public:
	explicit ImageAnimation(AnimationSet& anim_set);
	~ImageAnimation();
	
	virtual void Update(float dt);
	void Initialize(pugi::xml_node& anim_node, const std::string& base_dir);
private:
	typedef std::pair<float, ImagePtr> TimeAndImage;
	std::vector<TimeAndImage> m_images;
	int m_current_image;
	float m_time_from_start;
	AnimationSet& m_anim_set;
};

class PositionAnimation: public BaseAnimation
{
public:
	explicit PositionAnimation(AnimationSet& anim_set);
	~PositionAnimation();
	
	virtual void Update(float dt);
	void Initialize(pugi::xml_node& anim_node, const std::string& base_dir);
private:
	typedef std::pair<float, sf::Vector3f> TimeAndVec3;
	std::vector<TimeAndVec3> m_positions;
	int m_current_pos;
	float m_time_from_start;
	AnimationSet& m_anim_set;
};

class AlphaAnimation: public BaseAnimation
{
public:
	explicit AlphaAnimation(AnimationSet& anim_set);
	~AlphaAnimation();
	
	virtual void Update(float dt);
	void Initialize(pugi::xml_node& anim_node, const std::string& base_dir);
private:
	typedef std::pair<float, float> TimeAndAlpha;
	std::vector<TimeAndAlpha> m_alpha_values;
	int m_current_pos;
	float m_time_from_start;
	AnimationSet& m_anim_set;
};

class RotationZAnimation: public BaseAnimation
{
public:
	explicit RotationZAnimation(AnimationSet& anim_set);
	~RotationZAnimation();
	
	virtual void Update(float dt);
	void Initialize(pugi::xml_node& anim_node, const std::string& base_dir);
private:
	typedef std::pair<float, float> TimeAndAngle;
	std::vector<TimeAndAngle> m_angle_values;
	int m_current_pos;
	float m_time_from_start;
	AnimationSet& m_anim_set;
};

class AnimationSet {
public:
	AnimationSet();
	~AnimationSet();
	
	void Initialize(pugi::xml_node& anim_set_node, const std::string& base_bir);
	void Update(float dt);
	void Render(sf::RenderWindow&) const;
	void SetImage(ImagePtr& image) {m_currentImage = image;}
	ImagePtr& GetImage() { return m_currentImage; }
	void SetPosition(sf::Vector3f& pos) {m_currentPos = pos;}
	void SetAlpha(float alpha) {m_current_alpha = alpha;}
	void SetRotationZ(float angle) { m_current_angle = angle;}
	void Clear();
private:
	ImagePtr m_currentImage;
	sf::Vector3f m_currentPos;
	float m_current_alpha;
	float m_current_angle;
	//std::vector<sf::Vector3f> m_positions;
	//std::vector<float> m_scales;
	//std::vector<float> m_alphas;
	typedef boost::shared_ptr<BaseAnimation> AnimPtr;
	std::vector<AnimPtr> m_animations;
	std::string m_base_dir;
	bool m_looped;
};

#endif // ANIMATIONSET_H
